function FloatingWindow() {


	/**
	 * Floating window position and dimension
	 *
	 * @private
	 * @property  floatingPosition
	 * @type      {MessCoordinate}
	 */
	this.floatingPosition = new MessCoordinate(200, 100);
	this.floatingPosition.setDeltaX(300);
	this.floatingPosition.setDeltaY(300);

	/**
	 * Normalized window position and dimension
	 *
	 * @private
	 * @property  floatingPositionOld
	 * @type      {MessCoordinate}
	 * @default   null
	 */
	this.floatingPositionOld = null;
}
FloatingWindow.prototype = new Window();
FloatingWindow.prototype.toString = function() { return "js.mess.ui.controls.windows.FloatingWindow"; };
MessUIElement.prototype.addTagMapping("floatingWindow", "FloatingWindow");


	/**
	 * Build window content DOM representation
	 *
	 * @public
	 * @method  buildWindowContentDOM
	 * @return  {DOM} window content dom
	 */
	FloatingWindow.prototype.buildWindowContentDOM = function() {

		var content = DIV();
			content.id = this.id+":content";
			content.className = this.getCssPrefix() + this.CONTENT_CSS_SUFFIX;

		this.windowContentDom = content;

		return content;
	};

	/**
	 * Update window DOM object
	 *
	 * @public
	 * @method  updateDomObject
	 */
	FloatingWindow.prototype.updateDomObject = function(object) {

		// handle floating window dom representation
		//
        this.setDomObject(object);

        // make this window floating
        object.style.position = "absolute";

        // update floating window dimentions
        this.updateFloatingWindowSize(object);
	};

	/**
	 * Update floating window size using local floating* properties
	 *
	 * @private
	 * @method  updateFloatingWindowSize
	 * @param   {DOM} object   dom window representation
	 */
	FloatingWindow.prototype.updateFloatingWindowSize = function() {

		var object = this.domObject;
		var args = FloatingWindow.prototype.updateFloatingWindowSize.arguments;
		if (args.length === 1) {
			object = args[0];
		}
		else if (args.length === 3) {
			object = args[0];
			this.floatingPosition.setDeltaX(args[1]);
			this.floatingPosition.setDeltaY(args[2]);
		}

		// top, left, width, height
		this.setTop(this.floatingPosition.getY(), object);
		this.setLeft(this.floatingPosition.getX(), object);
		this.setControlWidth(this.floatingPosition.getDeltaX(), object);
		this.setControlHeight(this.floatingPosition.getDeltaY(), object);

		// resize button position
		this.updateResizeButtonPosition();
	};

	/**
	 * Remembers (floating) window current position
	 *
	 * @private
	 * @method   rememberWindowPosition
	 */
	FloatingWindow.prototype.rememberWindowPosition = function() {

		// remember coordinates
		this.floatingPositionOld = new MessCoordinate(this.getLeft(), this.getTop());
		// remember dimensions
		this.floatingPositionOld.setDeltaX(this.getWidth());
		this.floatingPositionOld.setDeltaY(this.getHeight());
	}

	/**
	 * Update floating window position using 'floating' properties
	 *
	 * @private
	 * @method  updateFloatingWindowPosition
	 * @param   {Number}  left   'new' left position
	 * @param   {Number}  top    'new' top postion
	 */
	FloatingWindow.prototype.updateFloatingWindowPosition = function(left, top) {

		// update floating position
		if (FloatingWindow.prototype.updateFloatingWindowPosition.arguments.length === 2) {
			this.floatingPosition.setX(left);
			this.floatingPosition.setY(top);
		}

		this.setLeft(this.floatingPosition.getX());
		this.setTop(this.floatingPosition.getY());
	};

	/**
	 * Update position of resize button
	 *
	 * @private
	 * @method  updateFloatingButtonPosition
	 */
	FloatingWindow.prototype.updateResizeButtonPosition = function() {

		// find resize button in collection
		if (this.resizeButton !== null) {
			this.resizeButton.updateButtonPosition();
		}
	};


    /**
    * Attaches basic event handlers for window object
    *
    * @private
    * @method attachEventHandlers
    */
    FloatingWindow.prototype.attachEventHandlers = function() {

        // mouse over
	    eventUtil.addEventHandler(this.windowHeaderDom, "mouseover", FloatingWindow.prototype.onMouseOverHandler);
        // mouse out
		eventUtil.addEventHandler(this.windowHeaderDom, "mouseout", FloatingWindow.prototype.onMouseOutHandler);
		// doubleclick on header
		eventUtil.addEventHandler(this.windowHeaderDom, "dblclick", FloatingWindow.prototype.onDoubleClickHandler);
		// mousedown on header
		eventUtil.addEventHandler(this.windowHeaderDom, "mousedown", FloatingWindow.prototype.onMouseDownHandler);
    };


	/**
	 * Handles mousedown on window header
	 *
	 * @event
	 * @method  onMouseDownHandler
	 */
	FloatingWindow.prototype.onMouseDownHandler = function() {

		var oEvent = eventUtil.getEvent();
		var oSource = eventUtil.getSource(oEvent);

		var window = null;
		var target = FloatingWindow.prototype.objects.get(oSource.id);

        if (target instanceof Window) {
        // window receiving event
            window = target;
        }

        if (window !== null) {
        	window.activateMoving(oEvent);
        }
	};

	/**
	 * Handles mouse dobuleclick on window header - maximize/minimize action
	 *
	 * @event
	 * @method  onMouseDownHandler
	 */
	FloatingWindow.prototype.onDoubleClickHandler = function() {

		var oEvent = eventUtil.getEvent();
		var oSource = eventUtil.getSource(oEvent);

		var window = null;
		var target = FloatingWindow.prototype.objects.get(oSource.id);

        if (target instanceof Window) {
        // window receiving event
            window = target;
        }

        if (window !== null) {
        	if (window.isMaximized()) {
                window.normalize();
            }
            else {
                window.maximize();
            }
        }
	};

    /**
	 * Floating left property getter
	 *
	 * @public
	 * @method  getFloatingLeft
	 * @return  {Number}
	 */
	FloatingWindow.prototype.getFloatingLeft = function() {

		return this.floatingPosition.getX();
	};

	/**
	 * Floating left property setter
	 *
	 * @public
	 * @method  setFloatingLeft
	 * @param   {Number} left
	 */
	FloatingWindow.prototype.setFloatingLeft = function(left) {

		this.floatingPosition.setX(left);
	};

	/**
	 * Floating top property getter
	 *
	 * @public
	 * @method  getFloatingTop
	 * @return  {Number}
	 */
	FloatingWindow.prototype.getFloatingTop = function() {

		return this.floatingPosition.getY();
	};

	/**
	 * Floating top property setter
	 *
	 * @public
	 * @method  setFloatingTop
	 * @param   {Number} top
	 */
	FloatingWindow.prototype.setFloatingTop = function(top) {

		this.floatingPosition.setY(top);
	};

	/**
	 * Floating width property getter
	 *
	 * @public
	 * @method  getFloatingWidth
	 * @return  {Number}
	 */
	FloatingWindow.prototype.getFloatingWidth = function() {

		return this.floatingPosition.getDeltaX();
	};

	/**
	 * Floating width property setter
	 *
	 * @public
	 * @method  setFloatingWidth
	 * @param   {Number} width
	 */
	FloatingWindow.prototype.setFloatingWidth = function(width) {

		this.floatingPosition.setDeltaX(width);
	};

	/**
	 * Floating height property getter
	 *
	 * @public
	 * @method  getFloatingHeight
	 * @return  {Number}
	 */
	FloatingWindow.prototype.getFloatingHeight = function() {

		return this.floatingPosition.getDeltaY();
	};

	/**
	 * Floating height property setter
	 *
	 * @public
	 * @method  setFloatingHeight
	 * @param   {Number} height
	 */
	FloatingWindow.prototype.setFloatingHeight = function(height) {

		this.floatingPosition.setDeltaY(height);
	};

     /**
      * Shows window - used only if window in floating mode
      *
      * @public
      * @method  show
      */
     FloatingWindow.prototype.show = function() {

        //if (this.parent === null) {
        // top level
            document.body.appendChild(this.render());
        //}
       // else {
            // [TODO: handle it here (nested floating win)
       //     this.parent.render().appendChild(this.render());
        //}
     };

	/**
	 * Activates floating window - root panels will have a reference to active floating window
	 *
	 * @public
	 * @method  activateResizing
	 */
	FloatingWindow.prototype.activateResizing = function(oEvent) {

        // build resizing frame and set as active control in root panel
        if (!this.isMaximized()) {
            this.getRootPanel().setActiveControl(this.buildResizingFrame(oEvent));
        }
    };

	/**
	 * Activates window moving (change of placement for floating window)
	 *
	 * @public
	 * @method  activateMoving
	 */
	FloatingWindow.prototype.activateMoving = function(oEvent) {

        // build moving frame and set as active control in root panel
        if (!this.isMaximized()) {
            this.getRootPanel().setActiveControl(this.buildMovingFrame(oEvent));
        }
    };

	/**
	 * 'after resizing' deactivation logic
	 *
	 * @public
	 * @method  finishResizing
	 * @param   {ResizingFrame}  child resizing frame control
	 * @param   {Number}  width    frame width
	 * @param   {Number}  height   frame height
	 */
	FloatingWindow.prototype.finishResizing = function(frame, width, height) {

        // destroy frame
        frame.destroy();

        // invalidate window size
        this.updateFloatingWindowSize(this.domObject, width, height);
        this.updateResizeButtonPosition();

        // deactivate resizing frame
        this.getRootPanel().setActiveControl(null);
	};

    /**
    * called from maximize button - maximize/normalize window
    *
    * @public
    * @method  maximizeWindow
    */
    FloatingWindow.prototype.maximizeWindow = function() {

        if (this.isMaximized()) {
            this.normalize();
        }
        else {
            this.maximize();
        }
    };

    /**
	 * Performs window maximalization
	 *
	 * @public
	 * @method  maximize
	 */
	FloatingWindow.prototype.maximize = function() {

        this.maximized = true;

        // remember window position
        this.rememberWindowPosition();

        // set max window dimensions
        var area = this.getRootPanel().getMovingArea();

        // update z-index
        this.updateZIndex()
        // update size & position
        this.updateFloatingWindowPosition(area.getX(), area.getY());
        this.updateFloatingWindowSize(this.domObject, area.getDeltaX()-1, area.getDeltaY()-1);

        // buttons box update
        this.buildButtonsBox(true);
	};

	/**
	 * Normalize (demaximize) window
	 *
	 * @public
	 * @method  normalize
	 */
	FloatingWindow.prototype.normalize = function() {

		if (this.isMaximized()) {

			this.maximized = false;

			// restore old position and window dimension
			this.floatingPosition = this.floatingPositionOld;
			this.updateFloatingWindowSize();
			this.updateFloatingWindowPosition();

			// update buttons
			this.buildButtonsBox(true);
		}
	};

	/**
	 * 'after moving' deactivation logic
	 *
	 * @public
	 * @method  finishMoving
	 * @param   {MovingFrame} child moving frame control
	 * @param   {Number}  left   final left position
	 * @param   {Nmmber}  top    final top position
	 */
	FloatingWindow.prototype.finishMoving = function(frame, left, top) {

        // destroy frame
        frame.destroy();

        // invalidate window position
        this.updateFloatingWindowPosition(left, top);
        this.updateZIndex();
        this.updateResizeButtonPosition();

        // deactivate moving frame
        this.getRootPanel().setActiveControl(null);
	}

	/**
	 * Builds resizing frme, used to visualize window resizing process
	 *
	 * @private
	 * @method  buildResizingFrame
	 * @return  {ResizingFrame}  frame object
	 */
	FloatingWindow.prototype.buildResizingFrame = function(oEvent) {

		// build frame
		var frame = new ResizingFrame();
		 	frame.setParent(this);
			frame.setTheme(this.getTheme());
			frame.build();
			frame.initMouseDownPoint(oEvent);

		// render frame
		this.getRootPanel().render().appendChild(frame.render());

		return frame;
	}

	/**
	 * Builds moving frame, used to visualize window (floating) moving process
	 *
	 * @private
	 * @method  buildMovingFrame
	 * @return  {MovingFrame}  frame object
	 */
	FloatingWindow.prototype.buildMovingFrame = function(oEvent) {

		// build frame
		var frame = new MovingFrame();
			frame.setParent(this);
			frame.setTheme(this.getTheme());
			frame.build(oEvent);
			frame.initMouseDownPoint(oEvent);

		// render frame
		this.getRootPanel().render().appendChild(frame.render());

		return frame;
	};

    /**
    * Update window z-index so after movement it's the top window on the stack
    *
    * @private
    * @method  updateZIndex
    */
    FloatingWindow.prototype.updateZIndex = function() {

        var floaters = this.getRootPanel().getFloatingControls();
        // this window will have the heighest z-index, rest of the windows
        // will get the z-index decreased by 1 if previous higher than z-index of
        // current window
        for (var it = floaters.iterator(); it.hasNext();) {
            var win = it.next();
            if (win !== this) {
                // check z-index, decrease if necessary
                if (win.getZIndex() > this.getZIndex()) {
                    win.setZIndex(win.getZIndex()-1);
                }
            }
        }

        var winIdx = floaters.indexOf(this);
        floaters.get(winIdx).setZIndex(floaters.size()-1);
    }

    /**
    * Floating Window closing logic
    *
    * @public
    * @method  close
    */
    FloatingWindow.prototype.close = function() {
        // close inner control
        this.closeInnerControl();
        // destroy buttons
        this.destroyButtons();
        // let panel destroy this floating window
        this.getRootPanel().destroyFloatingWindow(this);
    }

    /**
    * Return content container height
    *
    * @public
    * @method  getControlContentHeight
    * @return  {Number} height in px of window content height
    */
    FloatingWindow.prototype.getControlContentHeight = function() {

        return this.getFloatingHeight() - this.getHeaderSize() - 1;
    };

    /**
    * Return content container width
    *
    * @public
    * @method  getControlContentWidth
    * @return  {Number} width in px of window content width
    */
    FloatingWindow.prototype.getControlContentWidth = function() {

        return this.getFloatingWidth() - 2;  // -2  for border widths
    };











